﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using RouterControl.Whs;
using RouterControl.Whs.SingletonService;

namespace RouterControl.WhsAddIn.ConsoleControls
{
    public partial class OnlineStatus : ConsoleControlBase
    {
        private DateTime _lastUpdate = DateTime.MinValue;

        public OnlineStatus(RouterControlConsoleTab2 tab)
			: base(tab)
		{
			if (_log.IsDebugEnabled)
				_log.Debug("Initialization start");

			try
			{
				InitializeComponent();
	
				this.lineBox.Header.Text = Properties.Resources.txtOnlineStatus;

                // loading text
                this.onlineStatusLabel.Text =
                    this.onlineStatusUptimeLabel.Text =
                    this.onlineStatusMaxUploadLabel.Text =
                    this.onlineStatusMaxDownloadLabel.Text =
                    Properties.Resources.txtLoading;

				// done
				if (_log.IsDebugEnabled)
					_log.Debug("Initialization done");
			}
			catch (Exception e)
			{
				_log.Fatal("Failed to initialize", e);

				throw;
			}
		}

        private void OnlineStatus_Load(object sender, EventArgs e)
        {
            if (_singletonService.Channel.IsSelectedDeviceFound())
                UpdateOnlineStatus();
            else
            {
                _tab.ResetState();

                return;
            }

            this.updateStatusTimer.Enabled = true;
        }

        private void UpdateOnlineStatus()
        {
            try
            {
                var cfg = _singletonService.Channel.GetSelectedDeviceConfigData();

                if (!cfg.HasValue)
                {
                    _log.Warn("no device selected");

                    return;
                }

                // router status
                if (!cfg.Value.ConnectionStatus.HasValue)
                {
                    this.onlineStatusLabel.Text = Properties.Resources.txtOnlineStatusUnsupported;
                    this.onlineStatusImgBox.Image = Microsoft.HomeServer.Common.Client.CommonImages.GrayIcon32;
                }
                else
                {
                    switch (cfg.Value.ConnectionStatus.Value)
                    {
                        case CommonInternetGateway.ConnectionStatusValues.Connected:
                            this.onlineStatusLabel.Text = Properties.Resources.txtOnlineStatusOnline;
                            this.onlineStatusImgBox.Image = Microsoft.HomeServer.Common.Client.CommonImages.GreenIcon32;
                            break;

                        case CommonInternetGateway.ConnectionStatusValues.Disconnected:
                            this.onlineStatusLabel.Text = Properties.Resources.txtOnlineStatusOffline;
                            this.onlineStatusImgBox.Image = Microsoft.HomeServer.Common.Client.CommonImages.RedIcon32;
                            break;

                        case CommonInternetGateway.ConnectionStatusValues.Connecting:
                        case CommonInternetGateway.ConnectionStatusValues.Authenticating:
                            this.onlineStatusLabel.Text = Properties.Resources.txtOnlineStatusInit;
                            this.onlineStatusImgBox.Image = Microsoft.HomeServer.Common.Client.CommonImages.YellowIcon32;
                            break;

                        case CommonInternetGateway.ConnectionStatusValues.Disconnecting:
                        case CommonInternetGateway.ConnectionStatusValues.PendingDisconnect:
                            this.onlineStatusLabel.Text = Properties.Resources.txtOnlineStatusDeinit;
                            this.onlineStatusImgBox.Image = Microsoft.HomeServer.Common.Client.CommonImages.YellowIcon32;
                            break;

                        case CommonInternetGateway.ConnectionStatusValues.Unconfigured:
                            this.onlineStatusLabel.Text = Properties.Resources.txtOnlineStatusNotAvailable;
                            this.onlineStatusImgBox.Image = Microsoft.HomeServer.Common.Client.CommonImages.GrayIcon32;
                            break;

                        default:
                            _log.Warn("Unknown config status (onlineStatusUpdater_RunWorkerCompleted): " + cfg.Value.ConnectionStatus.ToString());
                            break;
                    }
                }

                // upload
                if (cfg.Value.UploadMaxBitRate != null)
                {
                    this.onlineStatusMaxUploadLabel.Text = FormatHelpers.GetNiceDataRate(
                        cfg.Value.UploadMaxBitRate.Value
                        );
                }
                else
                {
                    this.onlineStatusMaxUploadLabel.Text = Properties.Resources.txtUnsupported;
                }

                // download
                if (cfg.Value.DownloadMaxBitRate != null)
                {
                    this.onlineStatusMaxDownloadLabel.Text = FormatHelpers.GetNiceDataRate(
                        cfg.Value.DownloadMaxBitRate.Value
                        );
                }
                else
                {
                    this.onlineStatusMaxDownloadLabel.Text = Properties.Resources.txtUnsupported;
                }

                // uptime
                if (cfg.Value.UptimeSeconds != null)
                {
                    var ts = new TimeSpan(
                        cfg.Value.UptimeSeconds.Value * TimeSpan.TicksPerSecond
                        );

                    this.onlineStatusUptimeLabel.Text = FormatHelpers.GetNiceTimeSpan(ts);
                    this.onlineStatusUptimeLabel.Tag = ts;

                    this.uptimeTimer.Enabled = true;
                }
                else
                {
                    this.onlineStatusUptimeLabel.Text = Properties.Resources.txtUnsupported;
                    this.onlineStatusUptimeLabel.Tag = null;

                    this.uptimeTimer.Enabled = false;
                }

                // finalize
                _lastUpdate = DateTime.Now;
            }
            catch (Exception ex)
            {
                _log.Fatal("Failed to update online status", ex);

                throw;
            }
        }

        private void updateStatusTimer_Tick(object sender, EventArgs e)
        {
            if (_singletonService.IsWindowsServiceRunning() != SingletonService2Factory.ServiceStatus.Running)
                return;

            UpdateOnlineStatus();
        }

        private void uptimeTimer_Tick(object sender, EventArgs e)
        {
            if ((this.onlineStatusUptimeLabel.Tag != null) &&
                (_lastUpdate != DateTime.MinValue))
            {
                var ts = (TimeSpan)this.onlineStatusUptimeLabel.Tag;

                var newTs = ts.Add(DateTime.Now.Subtract(_lastUpdate));

                this.onlineStatusUptimeLabel.Text = FormatHelpers.GetNiceTimeSpan(newTs);
            }
        }
    }
}
